package com.bocloud.cmp.dao.app.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;
import com.bocloud.cmp.dao.app.SoftwareDao;
import com.bocloud.cmp.entity.app.resource.Software;
import com.bocloud.common.model.Param;
import com.bocloud.common.model.SimpleBean;
import com.bocloud.common.utils.ListTool;
import com.bocloud.common.utils.MapTools;
import com.bocloud.database.core.intf.impl.JdbcGenericDao;
import com.bocloud.database.utils.SQLHelper;

/**
 * 
 * @author zjm
 * @date 2017年3月17日
 */
@Repository("softwareDao")
public class SoftwareDaoImpl extends JdbcGenericDao<Software, Long> implements SoftwareDao {

	@Override
	public Software query(Long id) throws Exception {
		String sql = "SELECT software.*, repository_software_info.namespace, "
				+ "repository_software_info.repository_id, registry. NAME AS registry_name, "
				+ "cu. NAME AS creator_name, mu. NAME AS mender_name " + "FROM software "
				+ "LEFT JOIN repository_software_info on repository_software_info.software_id = software.id "
				+ "LEFT JOIN registry on repository_software_info.repository_id = registry.id "
				+ "LEFT JOIN `user` cu on cu.id = software.creater_id "
				+ "LEFT JOIN `user` mu on  mu.id = software.mender_id "
				+ "WHERE software.is_deleted = 0 and software.id = :id";
		Map<String, Object> params = MapTools.simpleMap("id", id);
		List<Software> list = this.list(Software.class, sql, params);
		if (ListTool.isEmpty(list)) {
			return null;
		}
		return list.get(0);
	}

	@Override
	public List<Software> list(int page, int rows, List<Param> params, Map<String, String> sorter, String deptId)
			throws Exception {
		String sql = "SELECT software.*, repository_software_info.namespace, "
				+ "repository_software_info.repository_id, registry. NAME AS registry_name, "
				+ "cu. NAME AS creator_name, mu. NAME AS mender_name " + "FROM software "
				+ "LEFT JOIN repository_software_info on repository_software_info.software_id = software.id "
				+ "LEFT JOIN registry on repository_software_info.repository_id = registry.id "
				+ "LEFT JOIN `user` cu on cu.id = software.creater_id "
				+ "LEFT JOIN `user` mu on  mu.id = software.mender_id " + "LEFT JOIN  "
				+ "application_software_info on application_software_info.software_id = software.id "
				+ "WHERE software.is_deleted = 0 ";
		if (null != deptId) {
			sql += "and (software.dept_id in (:deptId) or repository_software_info.namespace = 'library')";
		}
		sql = SQLHelper.buildRawSql(sql, page, rows, params, sorter, "");
		Map<String, Object> paramMap = SQLHelper.getParam(params);
		paramMap.put("deptId", deptId);
		return this.list(Software.class, sql, paramMap);
	}

	@Override
	public List<SimpleBean> list(List<Param> params, Map<String, String> sorter, String deptId) throws Exception {
		String sql = "SELECT repository_software_info.namespace, software.* FROM software "
				+ "LEFT JOIN repository_software_info on repository_software_info.software_id = software.id "
				+ "WHERE software.is_deleted = 0 ";
		if (null != deptId) {
			sql += "and (software.dept_id in (:deptId) or repository_software_info.namespace = 'library')";
		}
		sql = SQLHelper.buildRawSql(sql, 1, Integer.MAX_VALUE, params, sorter, "");
		Map<String, Object> paramMap = SQLHelper.getParam(params);
		paramMap.put("deptId", deptId);
		List<Software> softwares = this.list(Software.class, sql, paramMap);
		List<SimpleBean> beans = new ArrayList<>();
		for (Software software : softwares) {
			if (StringUtils.isEmpty(software.getNamespace())) {
				beans.add(new SimpleBean(software.getId(), software.getName() + ":" + software.getVersion()));
			} else {
				beans.add(new SimpleBean(software.getId(),
						software.getNamespace() + "/" + software.getName() + ":" + software.getVersion()));
			}
		}
		return beans;
	}

	@Override
	public int count(List<Param> params, String deptId) throws Exception {
		String sql = "SELECT count(1) FROM software "
				+ "LEFT JOIN repository_software_info on repository_software_info.software_id = software.id "
				+ "LEFT JOIN registry on repository_software_info.repository_id = registry.id "
				+ "LEFT JOIN `user` cu on cu.id = software.creater_id "
				+ "LEFT JOIN `user` mu on  mu.id = software.mender_id "
				+ "LEFT JOIN  application_software_info on application_software_info.software_id = software.id "
				+ "WHERE software.is_deleted = 0 ";
		if (null != deptId) {
			sql += "and (software.dept_id in (:deptId) or repository_software_info.namespace = 'library')";
		}
		sql = SQLHelper.buildRawSql(sql, params, null, "");
		Map<String, Object> paramMap = SQLHelper.getParam(params);
		paramMap.put("deptId", deptId);
		return this.countQuery(sql, paramMap).intValue();
	}

	@Override
	public boolean deleteById(Long id, Long userId) throws Exception {
		String sql = "update software set is_deleted = true , gmt_modify = :gmtModify ,mender_id = :menderId where is_deleted = 0 and id = :id";
		Map<String, Object> params = MapTools.simpleMap("id", id);
		params.put("menderId", userId);
		params.put("gmtModify", new Date());
		return this.execute(sql, params) > 0;
	}

	@Override
	public Software getSoftwareByNameWithVersionAndNamespace(String name, String version, String namespace) throws Exception {
		String sql = "select software.* from software "
				+ "LEFT JOIN repository_software_info on repository_software_info.software_id = software.id "
				+ "where is_deleted = 0 and name = :name and version = :version and repository_software_info.namespace = :namespace ";
		Map<String, Object> params = MapTools.simpleMap("name", name);
		params.put("version", version);
		params.put("namespace", namespace);
		List<Software> list = list(Software.class, sql, params);
		if (ListTool.isEmpty(list)) {
			return null;
		}
		return list.get(0);
	}

	@Override
	public boolean deleteRegistrySoftwareInfo(Long id) throws Exception {
		String sql = "delete from repository_software_info where software_id = :id";
		Map<String, Object> params = MapTools.simpleMap("id", id);
		return this.execute(sql, params) >= 0;
	}

	@Override
	public boolean deleteSoftwareAppInfo(Long id) throws Exception {
		String sql = "delete from application_software_info where software_id = :id";
		Map<String, Object> params = MapTools.simpleMap("id", id);
		return this.execute(sql, params) >= 0;
	}

	@Override
	public boolean authorize(Long id, Long userId, Long deptId) throws Exception {
		String sql = "update software set dept_id = :deptId , gmt_modify = :gmtModify ,mender_id = :menderId where is_deleted = 0 and id = :id";
		Map<String, Object> params = MapTools.simpleMap("id", id);
		params.put("deptId", deptId);
		params.put("menderId", userId);
		params.put("gmtModify", new Date());
		return this.execute(sql, params) > 0;
	}

}
